'use strict';

const mqtt = require('mqtt');

const Utils = require('../utils');
const logger = Utils.logger(__filename);

module.exports = class Client {
  constructor(cmd, notify) {
    const server = this.server = cmd.server;
    const clientId = this.clientId = cmd.name;
    this.notify = (msg, err) => {
      if (err) {
        logger.warn(msg, err);
      } else {
        logger.trace(msg);
      }
      notify(msg);
    };

    const client = this.client = mqtt.connect(`mqtt://${server}`, {
      clientId
    });

    client.on('connect', () => {
      this.notify(`${clientId} connected to ${server}`);
    });

    client.on('reconnect', () => {
      this.notify(`${clientId} reconnected to ${server}`);
    });

    client.on('message', (topic, message) => {
      this.notify(`${clientId} receive topic ${topic} message: ${message}`);
    });

    client.on('error', (err) => {
      this.notify(`${clientId} connected to ${server} error`, err);
    });
  }

  publish(options) {
    this.notify(`${this.clientId} publish topic ${options.topic} message: ${options.message}`);
    this.client.publish(options.topic, options.message, {
      qos: options.qos
    });
  }

  subscribe(options) {
    this.notify(`${this.clientId} subscribe ${options.topic}`);
    this.client.subscribe(options.topic, {
      qos: 2
    });
  }

  unsubscribe(options) {
    this.notify(`${this.clientId} unsubscribe ${options.topic}`);
    this.client.unsubscribe(options.topic);
  }

  end(callback) {
    this.client.end(false, () => {
      this.notify(`${this.clientId} disconnet to ${this.server}`);
      callback && callback();
    });
  }
};
